"""状态管理器，用于跟踪各类任务的状态信息"""

import logging
import time
from typing import Dict, Any, Optional
from collections import defaultdict
import threading

logger = logging.getLogger('status_manager')

class StatusManager:
    """状态管理器，用于跟踪上传、工具调用和管理任务的状态"""
    
    _instance = None
    _lock = threading.RLock()
    
    def __new__(cls):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super(StatusManager, cls).__new__(cls)
                cls._instance._initialize()
        return cls._instance
    
    def _initialize(self):
        """初始化状态管理器"""
        # 存储上传状态
        self.upload_statuses = {}
        
        # 存储工具调用状态
        self.tool_statuses = {}
        
        # 存储管理员任务状态
        self.admin_statuses = {}
        
        # 存储各类任务的锁
        self.upload_locks = defaultdict(threading.RLock)
        self.tool_locks = defaultdict(threading.RLock)
        self.admin_locks = defaultdict(threading.RLock)
        
        # 全局锁
        self.global_lock = threading.RLock()
        
        logger.info("状态管理器已初始化")
    
    # 上传状态管理方法
    def add_upload_status(self, task_id: str, status: Dict[str, Any]) -> None:
        """添加上传任务状态
        
        Args:
            task_id: 任务ID
            status: 状态信息
        """
        with self.upload_locks[task_id]:
            self.upload_statuses[task_id] = status
            logger.debug(f"添加上传状态: task_id={task_id}, status={status}")
    
    def update_upload_status(self, task_id: str, updates: Dict[str, Any]) -> None:
        """更新上传任务状态
        
        Args:
            task_id: 任务ID
            updates: 要更新的状态字段
        """
        with self.upload_locks[task_id]:
            if task_id in self.upload_statuses:
                self.upload_statuses[task_id].update(updates)
                logger.debug(f"更新上传状态: task_id={task_id}, updates={updates}")
            else:
                logger.warning(f"尝试更新不存在的上传状态: task_id={task_id}")
    
    def get_upload_status(self, task_id: str) -> Optional[Dict[str, Any]]:
        """获取上传任务状态
        
        Args:
            task_id: 任务ID
            
        Returns:
            状态信息，如果任务不存在则返回None
        """
        with self.upload_locks[task_id]:
            status = self.upload_statuses.get(task_id)
            logger.debug(f"获取上传状态: task_id={task_id}, status={'存在' if status else '不存在'}")
            return status.copy() if status else None
    
    def delete_upload_status(self, task_id: str) -> bool:
        """删除上传任务状态
        
        Args:
            task_id: 任务ID
            
        Returns:
            删除是否成功
        """
        with self.upload_locks[task_id]:
            if task_id in self.upload_statuses:
                del self.upload_statuses[task_id]
                logger.debug(f"删除上传状态: task_id={task_id}")
                return True
            logger.warning(f"尝试删除不存在的上传状态: task_id={task_id}")
            return False
    
    def list_upload_statuses(self, status: Optional[str] = None) -> Dict[str, Dict[str, Any]]:
        """列出上传任务状态
        
        Args:
            status: 可选的状态筛选
            
        Returns:
            任务ID到状态信息的映射
        """
        with self.global_lock:
            result = {}
            for task_id, task_status in self.upload_statuses.items():
                if status is None or task_status.get('status') == status:
                    result[task_id] = task_status.copy()
            logger.debug(f"列出上传状态: 数量={len(result)}, status_filter={status}")
            return result
    
    # 工具调用状态管理方法
    def add_tool_status(self, task_id: str, status: Dict[str, Any]) -> None:
        """添加工具调用状态
        
        Args:
            task_id: 任务ID
            status: 状态信息
        """
        with self.tool_locks[task_id]:
            self.tool_statuses[task_id] = status
            logger.debug(f"添加工具状态: task_id={task_id}, status={status}")
    
    def update_tool_status(self, task_id: str, updates: Dict[str, Any]) -> None:
        """更新工具调用状态
        
        Args:
            task_id: 任务ID
            updates: 要更新的状态字段
        """
        with self.tool_locks[task_id]:
            if task_id in self.tool_statuses:
                self.tool_statuses[task_id].update(updates)
                logger.debug(f"更新工具状态: task_id={task_id}, updates={updates}")
            else:
                logger.warning(f"尝试更新不存在的工具状态: task_id={task_id}")
    
    def get_tool_status(self, task_id: str) -> Optional[Dict[str, Any]]:
        """获取工具调用状态
        
        Args:
            task_id: 任务ID
            
        Returns:
            状态信息，如果任务不存在则返回None
        """
        with self.tool_locks[task_id]:
            status = self.tool_statuses.get(task_id)
            logger.debug(f"获取工具状态: task_id={task_id}, status={'存在' if status else '不存在'}")
            return status.copy() if status else None
    
    def delete_tool_status(self, task_id: str) -> bool:
        """删除工具调用状态
        
        Args:
            task_id: 任务ID
            
        Returns:
            删除是否成功
        """
        with self.tool_locks[task_id]:
            if task_id in self.tool_statuses:
                del self.tool_statuses[task_id]
                logger.debug(f"删除工具状态: task_id={task_id}")
                return True
            logger.warning(f"尝试删除不存在的工具状态: task_id={task_id}")
            return False
    
    def list_tool_statuses(self, status: Optional[str] = None) -> Dict[str, Dict[str, Any]]:
        """列出工具调用状态
        
        Args:
            status: 可选的状态筛选
            
        Returns:
            任务ID到状态信息的映射
        """
        with self.global_lock:
            result = {}
            for task_id, task_status in self.tool_statuses.items():
                if status is None or task_status.get('status') == status:
                    result[task_id] = task_status.copy()
            logger.debug(f"列出工具状态: 数量={len(result)}, status_filter={status}")
            return result
    
    # 管理员任务状态管理方法
    def add_admin_status(self, task_id: str, status: Dict[str, Any]) -> None:
        """添加管理员任务状态
        
        Args:
            task_id: 任务ID
            status: 状态信息
        """
        with self.admin_locks[task_id]:
            self.admin_statuses[task_id] = status
            logger.debug(f"添加管理员任务状态: task_id={task_id}, status={status}")
    
    def update_admin_status(self, task_id: str, updates: Dict[str, Any]) -> None:
        """更新管理员任务状态
        
        Args:
            task_id: 任务ID
            updates: 要更新的状态字段
        """
        with self.admin_locks[task_id]:
            if task_id in self.admin_statuses:
                self.admin_statuses[task_id].update(updates)
                logger.debug(f"更新管理员任务状态: task_id={task_id}, updates={updates}")
            else:
                logger.warning(f"尝试更新不存在的管理员任务状态: task_id={task_id}")
    
    def get_admin_status(self, task_id: str) -> Optional[Dict[str, Any]]:
        """获取管理员任务状态
        
        Args:
            task_id: 任务ID
            
        Returns:
            状态信息，如果任务不存在则返回None
        """
        with self.admin_locks[task_id]:
            status = self.admin_statuses.get(task_id)
            logger.debug(f"获取管理员任务状态: task_id={task_id}, status={'存在' if status else '不存在'}")
            return status.copy() if status else None
    
    def delete_admin_status(self, task_id: str) -> bool:
        """删除管理员任务状态
        
        Args:
            task_id: 任务ID
            
        Returns:
            删除是否成功
        """
        with self.admin_locks[task_id]:
            if task_id in self.admin_statuses:
                del self.admin_statuses[task_id]
                logger.debug(f"删除管理员任务状态: task_id={task_id}")
                return True
            logger.warning(f"尝试删除不存在的管理员任务状态: task_id={task_id}")
            return False
    
    def list_admin_statuses(self, status: Optional[str] = None) -> Dict[str, Dict[str, Any]]:
        """列出管理员任务状态
        
        Args:
            status: 可选的状态筛选
            
        Returns:
            任务ID到状态信息的映射
        """
        with self.global_lock:
            result = {}
            for task_id, task_status in self.admin_statuses.items():
                if status is None or task_status.get('status') == status:
                    result[task_id] = task_status.copy()
            logger.debug(f"列出管理员任务状态: 数量={len(result)}, status_filter={status}")
            return result
    
    # 清理过期状态
    def cleanup_expired_statuses(self, max_age_seconds: int = 86400) -> Dict[str, int]:
        """清理过期的状态信息
        
        Args:
            max_age_seconds: 最大保留时间（秒），默认为1天
            
        Returns:
            各类状态清理的数量统计
        """
        current_time = time.time()
        cleaned_up = {
            'upload': 0,
            'tool': 0,
            'admin': 0
        }
        
        with self.global_lock:
            # 清理上传状态
            expired_uploads = []
            for task_id, status in self.upload_statuses.items():
                # 检查是否有时间戳并且是否过期
                if 'upload_time' in status and current_time - status['upload_time'] > max_age_seconds:
                    expired_uploads.append(task_id)
            
            for task_id in expired_uploads:
                self.delete_upload_status(task_id)
                cleaned_up['upload'] += 1
            
            # 清理工具状态
            expired_tools = []
            for task_id, status in self.tool_statuses.items():
                if 'created_at' in status and current_time - status['created_at'] > max_age_seconds:
                    expired_tools.append(task_id)
            
            for task_id in expired_tools:
                self.delete_tool_status(task_id)
                cleaned_up['tool'] += 1
            
            # 清理管理员状态
            expired_admins = []
            for task_id, status in self.admin_statuses.items():
                if 'created_at' in status and current_time - status['created_at'] > max_age_seconds:
                    expired_admins.append(task_id)
            
            for task_id in expired_admins:
                self.delete_admin_status(task_id)
                cleaned_up['admin'] += 1
            
            logger.info(f"清理过期状态完成: {cleaned_up}")
            return cleaned_up
    
    # 获取统计信息
    def get_stats(self) -> Dict[str, Any]:
        """获取状态管理器的统计信息
        
        Returns:
            统计信息字典
        """
        with self.global_lock:
            stats = {
                'upload_status_count': len(self.upload_statuses),
                'tool_status_count': len(self.tool_statuses),
                'admin_status_count': len(self.admin_statuses),
                'total_status_count': len(self.upload_statuses) + len(self.tool_statuses) + len(self.admin_statuses)
            }
            
            # 按状态分类统计
            upload_status_counts = defaultdict(int)
            for status in self.upload_statuses.values():
                upload_status_counts[status.get('status', 'unknown')] += 1
            stats['upload_status_by_type'] = dict(upload_status_counts)
            
            tool_status_counts = defaultdict(int)
            for status in self.tool_statuses.values():
                tool_status_counts[status.get('status', 'unknown')] += 1
            stats['tool_status_by_type'] = dict(tool_status_counts)
            
            admin_status_counts = defaultdict(int)
            for status in self.admin_statuses.values():
                admin_status_counts[status.get('status', 'unknown')] += 1
            stats['admin_status_by_type'] = dict(admin_status_counts)
            
            return stats


# 创建全局状态管理器实例
status_manager = StatusManager()

__all__ = [
    'StatusManager',
    'status_manager'
]